package pm.core;

import org.apache.log4j.Logger;
import pm.config.Configuration;
import pm.devices.DevicesModule;
import pm.devices.DevicesModuleListener;
import pm.devices.drives.Drive;
import pm.gui.GuiModule;
import pm.gui.GuiModuleListener;
import pm.oo.OOException;
import pm.oo.OOModule;
import pm.oo.OOModuleListener;

import java.io.File;
import java.math.BigDecimal;

/**
 * @author Anton Bernatski
 */
public class Core implements GuiModuleListener, DevicesModuleListener, OOModuleListener {

	private final static Logger logger = Logger.getLogger(Core.class);
	private final static Logger audit = Logger.getLogger("audit");

	protected Configuration configuration;

	/* Modules */
	protected GuiModule guiModule;
	protected OOModule ooModule;
	protected DevicesModule devicesModule;

	protected Session session = null;


	/* GuiModuleListener */

	public void openFile(final File file) {
		loadFile(file);
	}

	public void nextPage() {
		ooModule.nextPage();
	}

	public void previousPage() {
		ooModule.prevPage();
	}

	public void closeCurrentDocument() {
		ooModule.closeCurrentDocument();
	}

	public void print(final PrintProperties printProperties) {
		audit.info("Print operation. Print parameters: " + printProperties);
		ooModule.print(printProperties);
	}

	public void copy(final CopyProperties copyProperties) {
		audit.info("Copy without preview operation. Copy parameters: " + copyProperties);
		final File file = devicesModule.scanToFile();
		ooModule.printFile(file);
	}

	public void copyScan() {
		final File file = devicesModule.scanToFile();
		loadFile(file);
	}

	public void copyPrint(final CopyProperties copyProperties) {
		audit.info("Copy operation. Copy parameters: " + copyProperties);
		ooModule.print(copyProperties);
	}

	public void scan() {
		final File file = devicesModule.scanToFile();
		loadFile(file);
	}

	public void save(final String path) {
		audit.info("Scan save operation. File: " + path);
		session.setScansSaved(session.getScansSaved() + 1);
		guiModule.updateSessionState(session);
	}

	public void finish() {
		audit.info("Session finish. Session: " + session);
		final BigDecimal printPrice = configuration.getPrintPrice().multiply(BigDecimal.valueOf(session.getPrinted()));
		final BigDecimal scanSavedPrice = configuration.getScanPrice().multiply(BigDecimal.valueOf(session.getScansSaved()));
		final BigDecimal change = session.getInserted().subtract(printPrice).subtract(scanSavedPrice);
		audit.info("Change: " + change);
		devicesModule.ejectChange(change);
		session = null;
		audit.info("Session stop");
		guiModule.updateSessionState(null);
	}

	public void exit() {
		audit.info("Application stop");
		logger.info("Exiting application");
		ooModule.disconnect();
		System.exit(0);
	}


	/* OOModuleListener implementation */

	public void pagesPrinted(final int count) {
		session.setPrinted(session.getPrinted() + count);
		guiModule.updateSessionState(session);
	}


	/* DevicesModuleListener */

	public void drivesChanged(final Drive[] drives) {
		guiModule.setDrives(drives);
	}

	public void moneyInserted(final BigDecimal insertedMoney) {
		audit.info("Money inserted: " + insertedMoney);
		if (session == null) {
			session = new Session();
			audit.info("Session start");
		}
		session.setInserted(session.getInserted().add(insertedMoney));
		guiModule.updateSessionState(session);
	}


	private void loadFile(File file) {
		try {
			ooModule.load(file);
		} catch (OOException e) {
			guiModule.showFileChooseDialog();
			guiModule.showError("Error during opening file");
			logger.error("Error during opening file", e);
		}
	}
}
